﻿using demo.Interfaces;
using demo.Models.DTOs;
using demo.Models;
using demo.Models.Option;

namespace demo.Services
{
    public class ProductService : IProductService
    {
        private readonly IRepository<Product> _productRepository;
        private readonly IRepository<Inventory> _inventoryRepository;
        //private readonly IRepository<Inventory> _inventoryRepository;
        private readonly IRepository<StockInDetail> _stockInDetailRepository;
        private readonly IRepository<StockOutDetail> _stockOutDetailRepository;
        private readonly IRepository<SubCategory> _subCategoryRepository;
        private readonly IRepository<Category> _categoryRepository;

        public ProductService(IRepository<Product> productRepository, IRepository<Inventory> inventoryRepository, IRepository<StockInDetail> stockInDetailRepository, IRepository<StockOutDetail> stockOutDetailRepository, IRepository<SubCategory> subCategoryRepository, IRepository<Category> categoryRepository)
        {
            _productRepository = productRepository;
            _inventoryRepository = inventoryRepository;
            _stockInDetailRepository = stockInDetailRepository;
            _stockOutDetailRepository = stockOutDetailRepository;
            _subCategoryRepository = subCategoryRepository;
            _categoryRepository = categoryRepository;
        }

        //这个get方法得重写 有个更好的继承 来实现分页
        //public async Task<PageResult<List<ProductDto>>> GetProductsAsync(ProductSearchOption productSearchOption)
        //{
        //    int page = productSearchOption.PageNumber; 
        //        int pageSize = productSearchOption.PagseSize;
        //    var products = await _productRepository.GetAllAsync();
        //    var paginatedProducts = products
        //        .Where(p => !p.IsDiscontinued)
        //        .Skip((page - 1) * pageSize)
        //        .Take(pageSize)
        //        .ToList();


        //    var productDtos = paginatedProducts.Select(p => new ProductDto
        //    {
        //        ProductID = p.ProductID,
        //        ProductName = p.ProductName,
        //        Description = p.Description,
        //        StockQuantity = p.Inventory.Sum(i => i.Quantity),
        //        AveragePurchasePrice = p.StockInDetails.Any() ? p.StockInDetails.Average(s => s.PurchasePrice) : 0,
        //        AverageSalePrice = p.StockOutDetails.Any() ? p.StockOutDetails.Average(s => s.SalePrice) : 0
        //    }).ToList();

        //    var result = new PageResult<List<ProductDto>>()
        //    {
        //        TotalCount = await _productRepository.CountAsync(),
        //        PageIndex = page,
        //        PageSize = pageSize,
        //        Result = productDtos
        //    };

        //    return result;
        //}

        //不用外键 手动查询 注入的实体类
        //少了 已经出库的数量 一级品牌名 二级品牌名
        public async Task<int> GetAllProductsCountAsync()
        {
            return await _productRepository.GetAllCountAsync();
        }
        public async Task<List<ProductDto>> GetProductsAsync(int page, int pageSize)
        {
            // 获取所有未下架的产品
            var products = await _productRepository.GetAllAsync(); // 假设返回的是 IQueryable<Product>
            var paginatedProducts = products
                .Where(p => !p.IsDiscontinued)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToList();

            // 获取分页产品的 SubCategoryID 列表
            var subCategoryIds = paginatedProducts.Select(p => p.SubCategoryID).Distinct().ToList();

            // 查询二级品牌数据
            var subCategories = await _subCategoryRepository.GetAllAsync();
            var subCategoryData = subCategories
                .Where(sc => subCategoryIds.Contains(sc.SubCategoryID))
                .ToDictionary(sc => sc.SubCategoryID, sc => new { sc.SubCategoryName, sc.CategoryID });

            // 获取所有涉及的一级品牌 CategoryID
            var categoryIds = subCategoryData.Values.Select(sc => sc.CategoryID).Distinct().ToList();

            // 查询一级品牌数据
            var categories = await _categoryRepository.GetAllAsync();
            var categoryData = categories
                .Where(c => categoryIds.Contains(c.CategoryID))
                .ToDictionary(c => c.CategoryID, c => c.CategoryName);

            // 查询库存数据
            var productIds = paginatedProducts.Select(p => p.ProductID).ToList();
            var inventories = await _inventoryRepository.GetAllAsync();
            var inventoryData = inventories
                .Where(i => productIds.Contains(i.ProductID))
                .GroupBy(i => i.ProductID)
                .Select(g => new
                {
                    ProductID = g.Key,
                    TotalQuantity = g.Sum(i => i.Quantity)
                })
                .ToList();

            // 查询进货明细
            var stockInDetails = await _stockInDetailRepository.GetAllAsync();
            var stockInData = stockInDetails
                .Where(s => productIds.Contains(s.ProductID))
                .GroupBy(s => s.ProductID)
                .Select(g => new
                {
                    ProductID = g.Key,
                    AveragePurchasePrice = g.Average(s => s.PurchasePrice)
                }).ToList();

            // 查询出货明细
            var stockOutDetails = await _stockOutDetailRepository.GetAllAsync();
            var stockOutData = stockOutDetails
                .Where(s => productIds.Contains(s.ProductID))
                .GroupBy(s => s.ProductID)
                .Select(g => new
                {
                    ProductID = g.Key,
                    AverageSalePrice = g.Average(s => s.SalePrice),
                    TotalStockOutQuantity = g.Sum(s => s.Quantity)
                })
                .ToList();

            // 合并数据到 DTO
            var productDtos = paginatedProducts.Select(p => new ProductDto
            {
                ProductID = p.ProductID,
                ProductName = p.ProductName,
                Description = p.Description,
                StockQuantity = inventoryData.FirstOrDefault(i => i.ProductID == p.ProductID)?.TotalQuantity ?? 0,
                AveragePurchasePrice = stockInData.FirstOrDefault(s => s.ProductID == p.ProductID)?.AveragePurchasePrice ?? 0,
                AverageSalePrice = stockOutData.FirstOrDefault(s => s.ProductID == p.ProductID)?.AverageSalePrice ?? 0,
                TotalStockOutQuantity = stockOutData.FirstOrDefault(s => s.ProductID == p.ProductID)?.TotalStockOutQuantity ?? 0,
                BrandName = subCategoryData.ContainsKey(p.SubCategoryID) && categoryData.ContainsKey(subCategoryData[p.SubCategoryID].CategoryID)
                    ? categoryData[subCategoryData[p.SubCategoryID].CategoryID]
                    : "未知品牌",
                SubBrandName = subCategoryData.ContainsKey(p.SubCategoryID)
                    ? subCategoryData[p.SubCategoryID].SubCategoryName
                    : "未知品牌"
            }).ToList();

            return productDtos;
        }


        public async Task<ProductDto> SearchProductAsync(int? id = null, string name = null)
        {
            if (id == null && string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("必须提供 id 或 name 参数");
            }

            var products = await _productRepository.GetAllAsync();
            Product product = null;

            if (id != null)
            {
                product = products.FirstOrDefault(p => p.ProductID == id.Value);
            }
            else if (!string.IsNullOrWhiteSpace(name))
            {
                product = products.FirstOrDefault(p => p.ProductName.Contains(name));
            }

            if (product == null) return null;

            var inventories = await _inventoryRepository.GetAllAsync();
            var stockQuantity = inventories
                .Where(i => i.ProductID == product.ProductID)
                .Sum(i => i.Quantity);

            var stockInDetails = await _stockInDetailRepository.GetAllAsync();
            var averagePurchasePrice = stockInDetails
                .Where(s => s.ProductID == product.ProductID)
                .Select(s => (decimal?)s.PurchasePrice)
                .DefaultIfEmpty(0)
                .Average();

            var stockOutDetails = await _stockOutDetailRepository.GetAllAsync();
            var averageSalePrice = stockOutDetails
                .Where(s => s.ProductID == product.ProductID)
                .Select(s => (decimal?)s.SalePrice)
                .DefaultIfEmpty(0)
                .Average();

            return new ProductDto
            {
                ProductID = product.ProductID,
                ProductName = product.ProductName,
                Description = product.Description,
                StockQuantity = stockQuantity,
                AveragePurchasePrice = averagePurchasePrice,
                AverageSalePrice = averageSalePrice
            };
        }


        //这个筛选做的也有问题 我搞不明白要筛出来的值是多少 应该还是重新算
        public async Task<List<ProductDto>> FilterProductsAsync(int? categoryId, int? subCategoryId, decimal? minPurchasePrice, decimal? maxPurchasePrice)
        {
            // 获取所有产品
            var products = await _productRepository.GetAllAsync();

            // 如果传入了 categoryId，需要手动过滤 SubCategory 表
            if (categoryId.HasValue)
            {
                // 查询 SubCategory 表，获取符合条件的 SubCategoryID 列表
                var subCategories = await _subCategoryRepository.GetAllAsync();
                var subCategoryIds = subCategories
                    .Where(sc => sc.CategoryID == categoryId.Value)
                    .Select(sc => sc.SubCategoryID)
                    .ToList();

                // 过滤产品
                products = products.Where(p => subCategoryIds.Contains(p.SubCategoryID)).ToList();
            }

            // 如果传入了 subCategoryId，直接过滤产品
            if (subCategoryId.HasValue)
            {
                products = products.Where(p => p.SubCategoryID == subCategoryId.Value).ToList();
            }

            // 获取产品 ID 列表
            var productIds = products.Select(p => p.ProductID).ToList();

            // 查询 StockInDetails 表
            var stockInDetails = await _stockInDetailRepository.GetAllAsync();

            // 如果传入了价格区间，过滤符合条件的入库价格
            if (minPurchasePrice.HasValue || maxPurchasePrice.HasValue)
            {
                stockInDetails = stockInDetails
                    .Where(s =>
                        (!minPurchasePrice.HasValue || s.PurchasePrice >= minPurchasePrice.Value) &&
                        (!maxPurchasePrice.HasValue || s.PurchasePrice <= maxPurchasePrice.Value))
                    .ToList();

                // 获取符合价格区间的产品 ID 列表
                var filteredProductIdsByPrice = stockInDetails.Select(s => s.ProductID).Distinct().ToList();

                // 过滤产品
                products = products.Where(p => filteredProductIdsByPrice.Contains(p.ProductID)).ToList();
                productIds = products.Select(p => p.ProductID).ToList(); // 更新产品 ID 列表
            }

            // 查询 Inventory 表
            var inventories = await _inventoryRepository.GetAllAsync();
            var inventoryData = inventories
                .Where(i => productIds.Contains(i.ProductID)) // 过滤符合条件的库存
                .GroupBy(i => i.ProductID) // 按 ProductID 分组
                .Select(g => new
                {
                    ProductID = g.Key, // 分组的键
                    TotalQuantity = g.Sum(i => i.Quantity) // 计算总数量
                })
                .ToList(); // 将结果转为列表

            // 计算平均入库价格
            var stockInData = stockInDetails
                .Where(s => productIds.Contains(s.ProductID))
                .GroupBy(s => s.ProductID)
                .Select(g => new
                {
                    ProductID = g.Key,
                    AveragePurchasePrice = g.Average(s => s.PurchasePrice)
                }).ToList();

            // 查询 StockOutDetails 表
            var stockOutDetails = await _stockOutDetailRepository.GetAllAsync();
            var stockOutData = stockOutDetails
                .Where(s => productIds.Contains(s.ProductID))
                .GroupBy(s => s.ProductID)
                .Select(g => new
                {
                    ProductID = g.Key,
                    AverageSalePrice = g.Average(s => s.SalePrice)
                })
                .ToList();

            // 构建 ProductDto 列表
            var productDtos = products.Select(p => new ProductDto
            {
                ProductID = p.ProductID,
                ProductName = p.ProductName,
                Description = p.Description,
                StockQuantity = inventoryData.FirstOrDefault(i => i.ProductID == p.ProductID)?.TotalQuantity ?? 0,
                AveragePurchasePrice = stockInData.FirstOrDefault(s => s.ProductID == p.ProductID)?.AveragePurchasePrice ?? 0,
                AverageSalePrice = stockOutData.FirstOrDefault(s => s.ProductID == p.ProductID)?.AverageSalePrice ?? 0
            }).ToList();

            return productDtos;
        }

        public async Task AddProductAsync(AddProductDto productDto)
        {
            var product = new Product
            {
                ProductName = productDto.ProductName,
                SubCategoryID = productDto.SubCategoryID,
                ImagePath = productDto.ImagePath,
                Description = productDto.Description,
                IsDiscontinued = false
            };

            await _productRepository.AddAsync(product);
        }

        public async Task UpdateProductAsync(UpdateProductDto productDto)
        {
            var product = await _productRepository.GetByIdAsync(productDto.ProductID);
            if (product == null) return;

            product.ProductName = productDto.ProductName;
            product.SubCategoryID = productDto.SubCategoryID;
            product.ImagePath = productDto.ImagePath;
            product.Description = productDto.Description;

            await _productRepository.UpdateAsync(product);
        }

        public async Task DeleteProductAsync(int productId)
        {
            var product = await _productRepository.GetByIdAsync(productId);
            if (product == null) return;

            product.IsDiscontinued = true;
            await _productRepository.UpdateAsync(product);
        }


    };
 
}

